﻿using System;
using System.Drawing;
using System.Windows.Forms;
using BackEndProcessorInterface.Properties;
using CppProject;

namespace BackEndProcessorInterface
{

    public partial class ConsoleForm : Form
    {
        private static int mousex;
        private static int mousey;

        private static bool _CLOSE;
        private static bool LOCK_PANEL_GRAPHIC;
        private static CppController controller;
        private ContextMenu _contextMenuRight;
        private ContextMenu _contextMenuLeft;

        private static readonly WorkConsole consoleWork = new WorkConsole { ShowInTaskbar = false };
      
        private static readonly Cursor defaultCursor = Cursors.Default;
        private static readonly Cursor crossCursor = Cursors.Cross;
        private static Cursor nowCursor = Cursors.Default;
        private static int oldWidth ;
        private static int oldHeight ;
        private static int panelPreferWidth;
        private static int panelPreferHeight;
        //My Cursors
        private static Cursor blackShadow;
        private static bool SHOW_CONTEXT_MENU;
        private static readonly ToolTip toolTip = new ToolTip { AutomaticDelay = 1000 };

        // private static readonly Brush brushString = new SolidBrush(Color.Black);

        public ConsoleForm(CppController cppController)
        {
            InitializeComponent();
          //  var toolTip = new ToolTip { AutomaticDelay = 1000 };
            toolTip.SetToolTip(panelGraphics, "Графическая консоль");
            toolTip.SetToolTip(labelTask, "Задача");
            toolTip.SetToolTip(labelCursor, "Тип указателя мыши");
            toolTip.SetToolTip(groupBoxMouse, "Положение курсора");
            toolTip.SetToolTip(groupBoxCursor, "Тип курсора");
            toolTip.SetToolTip(statusBar, "Состояние");
            toolTip.SetToolTip(groupBoxСontroller, "Команды контроллеру");
            toolTip.SetToolTip(buttonLock, "Блокировать облать рисования (Вкл/Выкл)");
            toolTip.SetToolTip(buttonContext, "Отображать контекстное меню (Вкл/Выкл)");

            controller = cppController;
            controller.SetWindow(panelGraphics.Handle);

            try
            {
                blackShadow = new Cursor(GetType(), "my_aero_arrow_xl.cur");
            }
            catch (NullReferenceException nr)
            {
                SetText("Error: " + nr.Message);
                blackShadow = Cursor.Current;
            }
            catch (ArgumentException ae)
            {
                SetText("Error: " + ae.Message);
                blackShadow = Cursor.Current;
            }
        }
        public ContextMenu SetLeftContextMenu
        {
            get { return _contextMenuLeft;}
            set { _contextMenuLeft = value;
            }
        }
        public  ContextMenu SetRightContextMenu
        {
            get { return _contextMenuRight; }
            set
            {
                _contextMenuRight = value;
                if(SHOW_CONTEXT_MENU)
                panelGraphics.ContextMenu = _contextMenuRight;
            }
        }
        /// <summary>
        /// Region[FLAG] on/off
        /// </summary>
        private static bool MOUSE_FLAG;

        public bool PaintMouseFlag
        {
            set { MOUSE_FLAG = value; }
            get { return MOUSE_FLAG; }
        }

     //   private const int MOUSE_CLICK = 1;
        /*
                private const int NOT_REACTION = -1;
        */



        private static bool PAINT_AXIS;
        public bool PaintAxis
        {
            set { PAINT_AXIS = value; controller.ApplyGraphicsSettings(PAINT_AXIS, PAINT_MESH, PAINT_MESH_FI, PAINT_ISOLINE, PAINT_FLAGS); }
            get { return PAINT_AXIS; }
        }
        private static bool PAINT_MESH;
        public bool PaintMesh
        {
            set { PAINT_MESH = value; controller.ApplyGraphicsSettings(PAINT_AXIS, PAINT_MESH, PAINT_MESH_FI, PAINT_ISOLINE, PAINT_FLAGS); }
            get { return PAINT_MESH; }
        }
        private static bool PAINT_MESH_FI;
        public bool PaintMeshFi
        {
            set { PAINT_MESH_FI = value; controller.ApplyGraphicsSettings(PAINT_AXIS, PAINT_MESH, PAINT_MESH_FI, PAINT_ISOLINE, PAINT_FLAGS); }
            get { return PAINT_MESH_FI; }
        }
        private static bool PAINT_ISOLINE;
        public bool PaintIsoline
        {
            set { PAINT_ISOLINE = value; controller.ApplyGraphicsSettings(PAINT_AXIS, PAINT_MESH, PAINT_MESH_FI, PAINT_ISOLINE, PAINT_FLAGS); }
            get { return PAINT_ISOLINE; }
        }
        private static bool PAINT_FLAGS;
        public bool PaintFlags
        {
            set { PAINT_FLAGS = value; controller.ApplyGraphicsSettings(PAINT_AXIS, PAINT_MESH, PAINT_MESH_FI, PAINT_ISOLINE, PAINT_FLAGS); }
            get { return PAINT_FLAGS; }
        }

     //   public int PAINT_STATE = -1;

        public bool CLOSE
        {
            set { _CLOSE = value; }
            get { return _CLOSE; }
        }
        public  void SetTask(string taskMessage)
        {
                labelTask.Text = taskMessage;
        }
        public void SetText(String textMessage)
        {
            consoleWork.SetText(textMessage);
        }
        public void _BorderVisible(bool val)
        {
            FormBorderStyle = val ? FormBorderStyle.None : FormBorderStyle.Sizable;
        }
        private void panelGraphics_MouseClick(object sender, MouseEventArgs e)
        {
          //  PAINT_STATE = MOUSE_CLICK;

            //             if (e.Button == MouseButtons.Right)
            //             {
            //                 controller.test(e.X, e.Y);
            //             }
            // 
            if (e.Button == MouseButtons.Left)
            {
                //controller.MoveViewport(150, 214, mousex, mousey);
                //controller.MoveViewport(e.X, e.Y, mousex, mousey);

                if (MOUSE_FLAG && controller.MouseInFlagMode)
                {
                    controller.AddFlag(e.X, e.Y);
                }
            }
        }

        private void panelGraphics_MouseDown(object sender, MouseEventArgs e)
        {
            if (!MOUSE_FLAG )
            {
                panelGraphics.Cursor = Cursors.Hand;
                SetTask("Drop Start...");
            }
        }
        
        private void panelGraphics_MouseMove(object sender, MouseEventArgs e)
        {
           
        if (MOUSE_FLAG == false && e.Button == MouseButtons.Left)
         {
           controller.MoveViewport(e.X, e.Y, mousex, mousey);
         }
            mousex = e.X;
            mousey = e.Y;
            labelCurrentMousePoint.Text = MouseLocationToString;
        }

        private void panelGraphics_MouseUp(object sender, MouseEventArgs e)
        {
            if (!MOUSE_FLAG)
            {
                panelGraphics.Cursor = nowCursor;
                SetTask("Drop End...");
            }
        }

        private void panelGraphics_Paint(object sender, PaintEventArgs e)
        {

            controller.ApplyGraphicsSettings(PAINT_AXIS, PAINT_MESH, PAINT_MESH_FI, PAINT_ISOLINE, PAINT_FLAGS);// DoPaint();
            //             var g = e.Graphics;
            //             switch(PAINT_STATE)
            //             {
            //                 case MOUSE_CLICK:
            //                     g.FillEllipse(Brushes.Red, mousex - 5, mousey - 5, 8, 8);
            //                     g.DrawString(MouseLocationToString, Font, brushString, new Point(mousex - 25, mousey - 14));
            //                     if (MOUSE_FLAG) panelGraphics.CreateGraphics().DrawImage(Resources.flag_16, lastPosition);
            //                     PAINT_STATE = NOT_REACTION;
            //                     break;
            //                 default:
            //                     break;
            //                     
            //             }
        }
        private static String MouseLocationToString
        {
            get { return String.Format("({0};{1})", mousex, mousey); }
        }

        private void cursorChooser_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawBackground();
            if (e.Index != -1)
            {
                e.Graphics.DrawImage(GetImage((cursorChooser.Items[e.Index].ToString())), e.Bounds.X, e.Bounds.Y);
                e.Graphics.DrawString("-" + cursorChooser.Items[e.Index], Font, Brushes.Black, e.Bounds.X + 18, e.Bounds.Y + 1);
                e.DrawFocusRectangle();
            }

        }

        private void ConsoleForm_Load(object sender, EventArgs e)
        {
            cursorChooser.Items.Add("Default");
            cursorChooser.Items.Add("Cross");
            cursorChooser.Items.Add("BlackShadow");
            cursorChooser.SelectedItem = 0;

            panelGraphics.Cursor = defaultCursor;

            var screenwidth = SystemInformation.PrimaryMonitorSize.Width * 2 / 3;
            var screenheight = SystemInformation.PrimaryMonitorSize.Height * 4 / 5;

            MaximumSize = new Size(screenwidth, screenheight);

            consoleWork.Show();

            oldWidth = Width;
            oldHeight = Height;

            panelPreferHeight = panelGraphics.Height;
            panelPreferWidth = panelGraphics.Width;
        }
        private static Bitmap GetImage(String itemName)
        {
            if (itemName != null)
                switch (itemName)
                {
                    case "Default":
                        return Resources.mouse_pointer_16;
                    case "Cross":
                        return Resources.cross_16x13;
                    case "BlackShadow":
                        return Resources.my_aero_arrow_xl;
                }
            return Resources.mouse_pointer_16;
        }

        private void cursorChooser_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (cursorChooser.SelectedIndex)
            {
                case 0:
                    nowCursor = panelGraphics.Cursor = defaultCursor;
                    break;
                case 1:
                    nowCursor = panelGraphics.Cursor = crossCursor;
                    break;
                case 2:
                    nowCursor = panelGraphics.Cursor = blackShadow;
                    break;
            }
            var text = string.Format("Тип: {0}", cursorChooser.SelectedItem);
            toolTip.SetToolTip(labelCursor,text);
            try
            {
                labelCursor.Text = text.Substring(0, 10) + "...";
            }
            catch (ArgumentOutOfRangeException) {
                labelCursor.Text = "Тип: "; }
           
        }
        private void ConsoleForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = !CLOSE;
            if (!CLOSE)
                Hide();

        }

        private void buttonClear_Click(object sender, EventArgs e)
        {
            SetText("Controller Clear Now!");
        }

        private void buttonResrash_Click(object sender, EventArgs e)
        {
            SetText("Controller Refrash Now!");
        }

        private void buttonLock_Click(object sender, EventArgs e)
        {
            if (LOCK_PANEL_GRAPHIC)
            {
                panelGraphics.Enabled = true;
                buttonLock.Text = "Блок Вкл";
            }
            else
            {
                panelGraphics.Enabled = false;
                buttonLock.Text = "Блок Выкл";
            }
            LOCK_PANEL_GRAPHIC = !LOCK_PANEL_GRAPHIC;
        }

        private void panelGraphics_Resize(object sender, EventArgs e)
        {
            /*
            var newWidth = panelGraphics.Width;
            var newHeight = panelGraphics.Height;
            SetText(string.Format("New size of panelGraphics: [Width = {0}, Heigth = {1}]", newWidth, newHeight));
            controller.ResizeGraphicWindow(panelGraphics.Handle, newWidth, newHeight);
             * */
        }
        private void ConsoleForm_KeyPress(object sender, KeyPressEventArgs e)
        {

            if (ModifierKeys == Keys.Control)
                //Ctrl+B
                if ((e.KeyChar & 0xF) == 2)
                    FormBorderStyle = (FormBorderStyle == FormBorderStyle.None) ? FormBorderStyle.Sizable : FormBorderStyle.None;
        }

        private void ConsoleForm_Resize(object sender, EventArgs e)
        {
            var deltaWidth = Width - oldWidth;
            var deltaHeight = Height - oldHeight;

            oldWidth = Width;
            oldHeight = Height;
           // var max = (deltaHeight > deltaWidth) ? deltaHeight : deltaWidth;

            var res = (deltaHeight > deltaWidth) ? panelGraphics.Height - panelPreferHeight : panelGraphics.Width - panelPreferWidth;
            
            panelGraphics.Width = panelGraphics.Height = panelPreferHeight + res; //делаем квадратной
            controller.ResizeGraphicWindow(panelGraphics.Handle, panelGraphics.Width, panelGraphics.Width);

            SetText(string.Format("New size of panelGraphics: [Width = {0}, Heigth = {1}]", panelGraphics.Width, panelGraphics.Height));

            panelGraphics.SetBounds(panelGraphics.Location.X, panelGraphics.Location.Y, panelPreferWidth + deltaWidth, panelPreferHeight + deltaHeight);

            panelPreferHeight = panelGraphics.Height;
            panelPreferWidth = panelGraphics.Width;
        }

        private void panelGraphics_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && SHOW_CONTEXT_MENU)
            {
                if (_contextMenuLeft != null) _contextMenuLeft.Show(panelGraphics, new Point(e.X, e.Y));
            }
        }

        private void buttonContext_Click(object sender, EventArgs e)
        {
            SHOW_CONTEXT_MENU = !SHOW_CONTEXT_MENU;

            if (SHOW_CONTEXT_MENU)
            {
                buttonContext.Text = "Меню Выкл";
                panelGraphics.ContextMenu = _contextMenuRight;
            }
            else
            {
                buttonContext.Text = "Меню Вкл";
                panelGraphics.ContextMenu = null;
            }
        }
    }
}
